# 导入pygame
import pygame
import random  # 随机库

GREEN = (0, 197, 205)
BlACK = (0, 0, 0)
# 窗口大小
width, height = 480, 700

# 自定义敌机出现的时间
CREATE_ENEMY = pygame.USEREVENT  # 自定义事件

# 初始化
pygame.init()
pygame.mixer.init()

# 创建游戏窗口
screen = pygame.display.set_mode((480, 700))

# 游戏名称
pygame.display.set_caption('飞机大作战')

# 设置系统时钟
clock = pygame.time.Clock()
pygame.time.set_timer(CREATE_ENEMY, 1000)  # 自定义事件出现的时间间隔（毫秒）

# 添加分数
score = 0  # 定义一个变量存放分数
score_font = pygame.font.SysFont('arial', 32)  # 创建一个font对象，显示结果
space_font = pygame.font.SysFont('arial', 32)
game_over_font = pygame.font.SysFont('arial', 32)
WhiteFont = (255, 255, 255)  # 定义字体的颜色

# 生命

life_NUM = 3
image = pygame.image.load("飞机/bomb.png")


# 添加背景音乐
# pygame.mixer.music.load('')
# pygame.mixer.music.set_volume(0.4)
# pygame.mixer.music.play(-1, 0)


class Hero(pygame.sprite.Sprite):
    def __init__(self, speed):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.image = pygame.image.load('飞机/hero.gif')
        self.rect = self.image.get_rect()  # 操作英雄
        self.rect.width *= 1
        self.rect.height *= 1
        self.image = pygame.transform.scale(self.image, (self.rect.width, self.rect.height))  # 自由缩放
        self.rect.x = 210  # x轴
        self.rect.y = 700 - 130  # y轴
        self.speed = speed
        self.ready_to_fire = 0

    # 更新
    def update(self, *args):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_UP]:  # 向上
            print('向上')

            self.rect.y -= self.speed
            if self.rect.y <= 0:
                self.rect.y = 0
        if keys[pygame.K_DOWN]:  # 向下
            print('向下')
            self.rect.y += self.speed
            if self.rect.y >= height - 100:
                self.rect.y = height - 100
        if keys[pygame.K_LEFT]:  # 向左
            print('向左')
            self.rect.x -= self.speed
            if self.rect.x <= 0:
                self.rect.x = 0
        if keys[pygame.K_RIGHT]:  # 向右
            print('向右')
            self.rect.x += self.speed
            if self.rect.x >= width - 100:
                self.rect.x = width - 100
        if keys[pygame.K_SPACE]:  # 发射子弹
            print('space')
            if self.ready_to_fire == 0:
                self.fire()
            self.ready_to_fire += 1
            if self.ready_to_fire > 5:
                self.ready_to_fire = 0
        else:
            self.ready_to_fire = 0

    def fire(self):
        #  发射子弹
        bullet = Hero_Bullet(10)  # 子弹速度为10
        bullet.rect.centerx = self.rect.centerx
        bullet.rect.centery = self.rect.centery
        hero_bullet_group.add(bullet)

        # sound = pygame.mixer.Sound('')
        # sound.play()


class Hero_Bullet(pygame.sprite.Sprite):
    # 初始化子弹
    def __init__(self, speed):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.image = pygame.image.load('飞机/bullet.png')
        self.rect = self.image.get_rect()
        self.speed = speed

    def update(self, *args):
        self.rect.y -= self.speed
        if self.rect.y < 0:
            self.kill()


class Enemy_Bullet(pygame.sprite.Sprite):
    # 初始化子弹
    def __init__(self, speed):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.image = pygame.image.load('飞机/bullet1.png')
        self.rect = self.image.get_rect()
        self.speed = speed

    def update(self, *args):
        self.rect.y += self.speed
        if self.rect.y > height:
            self.kill()


class Enemy(pygame.sprite.Sprite):
    def __init__(self, speed):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.image = pygame.image.load('飞机/enemy0.png')
        self.image_2 = pygame.image.load('飞机/enemy0.png')
        self.rect = self.image.get_rect()  # 操作英雄
        self.rect.x = random.randint(0, width - 100)
        self.speed = speed
        self.bullet_sum = 0
        self.fire()

    def update(self, *args):
        self.rect.y += 1
        # self.rect.x += 2
        if self.rect.y > height:
            self.kill()

    def fire(self):
        #  发射子弹
        bullet = Enemy_Bullet(5)  # 子弹速度为10
        bullet.rect.centerx = self.rect.centerx
        bullet.rect.centery = self.rect.centery
        enemy_bullet_group.add(bullet)


class Explode(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.images = [pygame.image.load('./飞机/enemy0_down' + str(i) + '.png') for i in
                       range(1, 5)]  # 包扎效果多个图片，改装成列表
        self.image_index = 0
        self.image = self.images[self.image_index]  # 取第一个图片
        self.rect = self.image.get_rect()
        self.ready_to_change = 0

        # sound = pygame.mixer.Sound('')
        # sound.play()

    def update(self, *args):
        if self.image_index < 2:
            self.ready_to_change += 1
            if self.ready_to_change % 5 == 0:
                self.image_index += 1
                self.image = self.images[self.image_index]  # 取第一个图片
        else:
            self.kill()


class Explode_hero(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.images = [pygame.image.load('./飞机/hero_blowup_n' + str(i) + '.png') for i in
                       range(1, 5)]  # 包扎效果多个图片，改装成列表
        self.image_index = 0
        self.image = self.images[self.image_index]  # 取第一个图片
        self.rect = self.image.get_rect()
        self.ready_to_change = 0

        # sound = pygame.mixer.Sound('')
        # sound.play()

    def update(self, *args):
        if self.image_index < 2:
            self.ready_to_change += 1
            if self.ready_to_change % 5 == 0:
                self.image_index += 1
                self.image = self.images[self.image_index]  # 取第一个图片
        else:
            self.kill()


class BackGround(pygame.sprite.Sprite):
    def __init__(self, is_alt=0):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.image = pygame.image.load('飞机/background.png')
        self.rect = self.image.get_rect()
        self.rect.y = is_alt

    def update(self, *args):
        self.rect.y += 10
        if self.rect.y > self.rect.height:
            self.rect.y = -self.rect.height

    def draw(self):
        # 绘制屏幕
        screen.blit(self.image, self.rect)


class Life(pygame.sprite.Sprite):
    def __init__(self, is_alt=0):
        pygame.sprite.Sprite.__init__(self)  # 运行方式
        self.image = pygame.image.load('飞机/bomb.png')
        self.rect = self.image.get_rect()
        self.rect.y = is_alt

    def update(self, *args):
        self.rect.y += 10
        if self.rect.y > self.rect.height:
            self.rect.y = -self.rect.height

    def draw(self):
        # 绘制屏幕
        screen.blit(self.image, self.rect)


# 初始化英雄,敌人
hero = Hero(10)  # 创建英雄和控制速度
bg = BackGround()
bg2 = BackGround(-700)
bg2.rect.y = bg.rect.height  # 连接两张图片

# 初始化精灵组
hero_group = pygame.sprite.Group()  # 全部精灵组q
hero_bullet_group = pygame.sprite.Group()
enemy_bullet_group = pygame.sprite.Group()
explode_group = pygame.sprite.Group()
bg_group = pygame.sprite.Group()
enemy_group = pygame.sprite.Group()
hero_group.add(hero)  # 添加英雄,敌人
bg_group.add(bg, bg2)

#  游戏循环
while True:
    # 设置刷新率
    clock.tick(60)
    # 玩家操作
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        if event.type == CREATE_ENEMY:
            enemy_group.add(Enemy(random.randint(1, 4)))

    # 碰撞检测
    herois = pygame.sprite.groupcollide(hero_group, enemy_group, False, pygame.sprite.collide_mask)

    enemy_bulletis = pygame.sprite.groupcollide(hero_group, enemy_bullet_group, False,
                                                pygame.sprite.collide_mask)
    if enemy_bulletis or herois:  # 如果产生重合那么就被击毁了
        hero_group.active = False  # 更改己方飞机的状态
        life_NUM -= 1
        for enemy in enemy_bulletis.keys() or herois.keys():
            explode = Explode_hero()
            explode.rect = enemy.rect
            explode_group.add(explode)
        if life_NUM == 0:
            hero_group.remove(hero)

            for enemy in enemy_bulletis.keys():
                explode = Explode_hero()
                explode.rect = enemy.rect
                explode_group.add(explode)
            while True:
                # 设置刷新率
                clock.tick(60)
                # 玩家操作
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        exit()
                for group in [bg_group, hero_group, enemy_group, hero_bullet_group, explode_group,
                              enemy_bullet_group]:
                    group.update()
                    # 屏幕更新
                    group.draw(screen)
                score_surface = score_font.render("Score : %s" % str(score), True, WhiteFont)

                # 将需要显示的文字转换成surface对象
                screen.blit(score_surface, (width - 340, height * 0.5))  # 将结果绘制出来
                game_over_surface = game_over_font.render('game_over', True,
                                                          WhiteFont)  # 将需要显示的文字转换成surface对象
                screen.blit(game_over_surface, (width - 340, height * 0.5 - 100))  # 将结果绘制出来
                pygame.display.update()
    # bg2_group.update()
    # bg2_group.draw(screen)
    # pygame.display.update()
    pygame.sprite.groupcollide(enemy_bullet_group, hero_bullet_group, True, True)
    collision = pygame.sprite.groupcollide(enemy_group, hero_bullet_group, True, True)  # 用collision接住pygame返回值
    for enemy in collision.keys():
        explode = Explode()
        explode.rect = enemy.rect
        explode_group.add(explode)
        score += 100
    # print('shu', bullet_group)
    # print('zd', enemy_group)
    for group in [bg_group, hero_group, enemy_group, hero_bullet_group, explode_group, enemy_bullet_group]:
        group.update()
        # 屏幕更新
        group.draw(screen)
    # 显示分数
    screen.blit(image, (210 + 120, 700 - 110))  # 生命绘制
    score_surface = score_font.render("Score : %s" % str(score), True, WhiteFont)  # 将需要显示的文字转换成surface对象
    Life_surface = score_font.render("X %s" % str(life_NUM), True, WhiteFont)
    screen.blit(Life_surface, (210 + 200, 700 - 100))
    screen.blit(score_surface, (0, 0))  # 将结果绘制出来
    pygame.display.update()




